library(beeswarm)
library(naniar)
library(zoo)
# install.packages("zoo")
library(janitor)
library(dplyr)
# install.packages("GGally")
# library(sets)
library(tidyverse)
library(ggplot2)
library(GGally) # for ggpairs
library(lubridate)

Attaching package: ‘lubridate’

The following objects are masked from ‘package:sets’:

    as.interval, interval, is.interval

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
# install.packages("maps")
# library(maps)
load_file <- function(file_path){
  read_csv(file_path)
}

tx_data <- load_file("./../data/COVID-19_cases_TX.csv")

── Column specification ───────────────────────────────────────────────────────────────────────────────────────────
cols(
  county_fips_code = col_character(),
  county_name = col_character(),
  state = col_character(),
  state_fips_code = col_double(),
  date = col_date(format = ""),
  confirmed_cases = col_double(),
  deaths = col_double()
)
global_mobility_report <- load_file("./../data/Global_Mobility_Report.csv")

── Column specification ───────────────────────────────────────────────────────────────────────────────────────────
cols(
  country_region_code = col_character(),
  country_region = col_character(),
  sub_region_1 = col_character(),
  sub_region_2 = col_logical(),
  metro_area = col_logical(),
  iso_3166_2_code = col_character(),
  census_fips_code = col_logical(),
  date = col_date(format = ""),
  retail_and_recreation_percent_change_from_baseline = col_double(),
  grocery_and_pharmacy_percent_change_from_baseline = col_double(),
  parks_percent_change_from_baseline = col_double(),
  transit_stations_percent_change_from_baseline = col_double(),
  workplaces_percent_change_from_baseline = col_double(),
  residential_percent_change_from_baseline = col_double()
)

4199216 parsing failures.
 row        col           expected                  actual                                   file
3036 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3037 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3038 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3039 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
3040 metro_area 1/0/T/F/TRUE/FALSE Kabul Metropolitan Area './../data/Global_Mobility_Report.csv'
.... .......... .................. ....................... ......................................
See problems(...) for more details.
cases_plus_census <- load_file("./../data/COVID-19_cases_plus_census.csv")

── Column specification ───────────────────────────────────────────────────────────────────────────────────────────
cols(
  .default = col_double(),
  county_fips_code = col_character(),
  county_name = col_character(),
  state = col_character(),
  state_fips_code = col_character(),
  date = col_date(format = ""),
  geo_id = col_character(),
  pop_5_years_over = col_logical(),
  speak_only_english_at_home = col_logical(),
  speak_spanish_at_home = col_logical(),
  speak_spanish_at_home_low_english = col_logical(),
  pop_15_and_over = col_logical(),
  pop_never_married = col_logical(),
  pop_now_married = col_logical(),
  pop_separated = col_logical(),
  pop_widowed = col_logical(),
  pop_divorced = col_logical()
)
ℹ Use `spec()` for the full column specifications.
cols_keep <- c("county_fips_code", "confirmed_cases", "deaths", "median_income", "male_pop", "female_pop", "total_pop", "median_age", "worked_at_home")
subset_census <- cases_plus_census[cols_keep]

cols_keep <- c("date", "retail_and_recreation_percent_change_from_baseline", "grocery_and_pharmacy_percent_change_from_baseline", "parks_percent_change_from_baseline", "transit_stations_percent_change_from_baseline", "workplaces_percent_change_from_baseline", "residential_percent_change_from_baseline")
subset_mobility <- global_mobility_report[cols_keep]
subset_mobility$date <- as.Date(subset_mobility$date, format="%Y-%m-%d")
# global_mobility_report
vis_miss(global_mobility_report, sort_miss = T, warn_large_data= F)

vis_miss(tx_data, sort_miss = T, warn_large_data= F)

vis_miss(subset_census, sort_miss = T, warn_large_data = F)

library(RColorBrewer)
plot_vs_county <- function(df, col_val, percentile=FALSE,
                           fips_title="county_fips_code", banks=6, 
                           legend_title="", graphic_title=""){
  # Subset for speed 
  df <- df[c(fips_title, col_val)]
  
  # Get county data
  gcounty <- ggplot2::map_data("county")
  # USA map data
  gusa <- map_data("state")
  
  if (banks > 9){
    mycolors <- colorRampPalette(brewer.pal(9, "Reds"))(banks)
  }
  
  # Format with subregions
  fipstab <-
      transmute(maps::county.fips, fips, county = sub(":.*", "", polyname)) %>%
      unique() %>%
      separate(county, c("region", "subregion"), sep = ",")
  
  # Combine in desired order (NA for missing)
  gcounty <- left_join(gcounty, fipstab, c("region", "subregion"))


  dis <- df
  dis$rprop <- rank(df[col_val])
  dis$pcls <- cut(100 * percent_rank(df[col_val]), seq(0, 100, len = banks),
                        include.lowest = TRUE)

  # Missing data
  anti_join(gcounty, dis, by = c("fips" = fips_title)) %>%
    select(region, subregion) %>%
    unique()
  gcounty_pop <- left_join(gcounty, dis, by = c("fips" = fips_title))
  fill_vals <- gcounty_pop[col_val]

  # Plot
  if (legend_title == ""){
    legend_title <- col_val
  }

  if (percentile == FALSE){
    # names(gcounty_pop)[names(gcounty_pop) == col_val] <- "col_of_interest"
    plt <- ggplot(gcounty_pop) +
      geom_polygon(aes(long, lat, group = group, fill = get(col_val)),
                   color = "grey", size = 0.1, name="Percent Infected") +
      geom_polygon(aes(long, lat, group = group),
                   fill = NA, data = gusa, color = "lightgrey") +
      coord_map("bonne", parameters = 41.6) + ggthemes::theme_map()+
      scale_fill_gradient2()
       # scale_fill_gradient(low = "white", high = "red", na.value = "grey")
      # scale_fill_gradientn(colours = terrain.colors(10))
  }

  if (percentile == TRUE){
    plt <- ggplot(gcounty_pop) +
      geom_polygon(aes(long, lat, group = group, fill = pcls),
                   color = "grey", size = 0.1) +
      geom_polygon(aes(long, lat, group = group),
                   fill = NA, data = gusa, color = "lightgrey") +
      coord_map("bonne", parameters = 41.6) + ggthemes::theme_map() +
      scale_fill_manual(values = mycolors, na.value = "grey") +
      # scale_fill_brewer(palette = "viridis", na.value = "grey") +
      theme(plot.title = element_text(family = "Helvetica", face = "bold", size = (15)),
            legend.background = element_rect(fill = NA), 
            legend.position = "left")
  }
  plt <- plt + labs(fill=legend_title) + ggtitle(graphic_title)
  plt
}
subset_census
subset_census['pct_infected'] <- subset_census['confirmed_cases']/subset_census['total_pop']
subset_census['pct_deaths'] <- subset_census['deaths']/subset_census['total_pop']
subset_census$county_fips_code <-as.integer(subset_census$county_fips_code)
subset_census
plot_vs_county(subset_census, "pct_infected", legend_title = "Percent Infected")
Ignoring unknown parameters: name

plot_vs_county(subset_census, "pct_infected", percentile = TRUE, banks=11, 
               legend_title = "Percentile Infected",
               graphic_title = "Percentile of Percentage of People Infected by County")

plot_vs_county(subset_census, "pct_deaths", percentile = TRUE, banks=11, 
               legend_title = "Percentile Deaths",
               graphic_title = "Percentile of Percentage of Deaths by County")

census_corr_cols <- c("deaths", "confirmed_cases", "median_income", "male_pop",
                      "female_pop", "total_pop", "median_age", "worked_at_home")
ggcorr(subset_census[census_corr_cols], low="red", mid="grey", high="blue", hjust= .75, size=3, 
       label = TRUE, label_size = 3, label_color = "white") + ggplot2::labs(title = "Pearson Correlation of Important Variables")

global_mobility_report
country_date_pct_change <- global_mobility_report %>% select(country_region_code
                                                             | contains("date") 
                                                             | contains("percent"))
country_date_pct_change
coi_downsampled <- country_date_pct_change %>% filter(country_region_code %in% 
                                                        c("US", "CA", "NZ")) %>% 
  filter(weekdays(date) == "Monday") %>% group_by(country_region_code, date) %>% summarise_all(mean, na.rm = T) %>% arrange(date)
coi_downsampled
ggplot(coi_downsampled,
       aes(x=date, y=grocery_and_pharmacy_percent_change_from_baseline, group=country_region_code,
                            color=country_region_code))+
  geom_point(aes(y=rollmean(retail_and_recreation_percent_change_from_baseline, k=20, na.pad=TRUE)), size=.5)

  # geom_line(aes(y=rollmean(retail_and_recreation_percent_change_from_baseline, k=50, na.pad=TRUE)))
  # geom_line()
coi_downsampled
LS0tCnRpdGxlOiAiQ2xlYW5lZCBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkoYmVlc3dhcm0pCmxpYnJhcnkobmFuaWFyKQpsaWJyYXJ5KHpvbykKIyBpbnN0YWxsLnBhY2thZ2VzKCJ6b28iKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoZHBseXIpCiMgaW5zdGFsbC5wYWNrYWdlcygiR0dhbGx5IikKIyBsaWJyYXJ5KHNldHMpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoR0dhbGx5KSAjIGZvciBnZ3BhaXJzCmxpYnJhcnkobHVicmlkYXRlKQojIGluc3RhbGwucGFja2FnZXMoIm1hcHMiKQojIGxpYnJhcnkobWFwcykKYGBgCgpgYGB7cn0KbG9hZF9maWxlIDwtIGZ1bmN0aW9uKGZpbGVfcGF0aCl7CiAgcmVhZF9jc3YoZmlsZV9wYXRoKQp9Cgp0eF9kYXRhIDwtIGxvYWRfZmlsZSgiLi8uLi9kYXRhL0NPVklELTE5X2Nhc2VzX1RYLmNzdiIpCmdsb2JhbF9tb2JpbGl0eV9yZXBvcnQgPC0gbG9hZF9maWxlKCIuLy4uL2RhdGEvR2xvYmFsX01vYmlsaXR5X1JlcG9ydC5jc3YiKQpjYXNlc19wbHVzX2NlbnN1cyA8LSBsb2FkX2ZpbGUoIi4vLi4vZGF0YS9DT1ZJRC0xOV9jYXNlc19wbHVzX2NlbnN1cy5jc3YiKQpgYGAKYGBge3J9CmNvbHNfa2VlcCA8LSBjKCJjb3VudHlfZmlwc19jb2RlIiwgImNvbmZpcm1lZF9jYXNlcyIsICJkZWF0aHMiLCAibWVkaWFuX2luY29tZSIsICJtYWxlX3BvcCIsICJmZW1hbGVfcG9wIiwgInRvdGFsX3BvcCIsICJtZWRpYW5fYWdlIiwgIndvcmtlZF9hdF9ob21lIikKc3Vic2V0X2NlbnN1cyA8LSBjYXNlc19wbHVzX2NlbnN1c1tjb2xzX2tlZXBdCgojIGNvbHNfa2VlcCA8LSBjKCJkYXRlIiwgInJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lIiwgImdyb2NlcnlfYW5kX3BoYXJtYWN5X3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUiLCAicGFya3NfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSIsICJ0cmFuc2l0X3N0YXRpb25zX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUiLCAid29ya3BsYWNlc19wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lIiwgInJlc2lkZW50aWFsX3BlcmNlbnRfY2hhbmdlX2Zyb21fYmFzZWxpbmUiKQojIHN1YnNldF9tb2JpbGl0eSA8LSBnbG9iYWxfbW9iaWxpdHlfcmVwb3J0W2NvbHNfa2VlcF0KIyBnbG8KIyBzdWJzZXRfbW9iaWxpdHkkZGF0ZSA8LSBhcy5EYXRlKHN1YnNldF9tb2JpbGl0eSRkYXRlLCBmb3JtYXQ9IiVZLSVtLSVkIikKYGBgCgpgYGB7cn0KIyBnbG9iYWxfbW9iaWxpdHlfcmVwb3J0CnZpc19taXNzKGdsb2JhbF9tb2JpbGl0eV9yZXBvcnQsIHNvcnRfbWlzcyA9IFQsIHdhcm5fbGFyZ2VfZGF0YT0gRikKYGBgCgoKYGBge3J9CnZpc19taXNzKHR4X2RhdGEsIHNvcnRfbWlzcyA9IFQsIHdhcm5fbGFyZ2VfZGF0YT0gRikKdmlzX21pc3Moc3Vic2V0X2NlbnN1cywgc29ydF9taXNzID0gVCwgd2Fybl9sYXJnZV9kYXRhID0gRikKYGBgCgpgYGB7cn0KbGlicmFyeShSQ29sb3JCcmV3ZXIpCnBsb3RfdnNfY291bnR5IDwtIGZ1bmN0aW9uKGRmLCBjb2xfdmFsLCBwZXJjZW50aWxlPUZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaXBzX3RpdGxlPSJjb3VudHlfZmlwc19jb2RlIiwgYmFua3M9NiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZF90aXRsZT0iIiwgZ3JhcGhpY190aXRsZT0iIil7CiAgIyBTdWJzZXQgZm9yIHNwZWVkIAogIGRmIDwtIGRmW2MoZmlwc190aXRsZSwgY29sX3ZhbCldCiAgCiAgIyBHZXQgY291bnR5IGRhdGEKICBnY291bnR5IDwtIGdncGxvdDI6Om1hcF9kYXRhKCJjb3VudHkiKQogICMgVVNBIG1hcCBkYXRhCiAgZ3VzYSA8LSBtYXBfZGF0YSgic3RhdGUiKQogIAogIGlmIChiYW5rcyA+IDkpewogICAgbXljb2xvcnMgPC0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDksICJSZWRzIikpKGJhbmtzKQogIH0KICAKICAjIEZvcm1hdCB3aXRoIHN1YnJlZ2lvbnMKICBmaXBzdGFiIDwtCiAgICAgIHRyYW5zbXV0ZShtYXBzOjpjb3VudHkuZmlwcywgZmlwcywgY291bnR5ID0gc3ViKCI6LioiLCAiIiwgcG9seW5hbWUpKSAlPiUKICAgICAgdW5pcXVlKCkgJT4lCiAgICAgIHNlcGFyYXRlKGNvdW50eSwgYygicmVnaW9uIiwgInN1YnJlZ2lvbiIpLCBzZXAgPSAiLCIpCiAgCiAgIyBDb21iaW5lIGluIGRlc2lyZWQgb3JkZXIgKE5BIGZvciBtaXNzaW5nKQogIGdjb3VudHkgPC0gbGVmdF9qb2luKGdjb3VudHksIGZpcHN0YWIsIGMoInJlZ2lvbiIsICJzdWJyZWdpb24iKSkKCgogIGRpcyA8LSBkZgogIGRpcyRycHJvcCA8LSByYW5rKGRmW2NvbF92YWxdKQogIGRpcyRwY2xzIDwtIGN1dCgxMDAgKiBwZXJjZW50X3JhbmsoZGZbY29sX3ZhbF0pLCBzZXEoMCwgMTAwLCBsZW4gPSBiYW5rcyksCiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGUubG93ZXN0ID0gVFJVRSkKCiAgIyBNaXNzaW5nIGRhdGEKICBhbnRpX2pvaW4oZ2NvdW50eSwgZGlzLCBieSA9IGMoImZpcHMiID0gZmlwc190aXRsZSkpICU+JQogICAgc2VsZWN0KHJlZ2lvbiwgc3VicmVnaW9uKSAlPiUKICAgIHVuaXF1ZSgpCiAgZ2NvdW50eV9wb3AgPC0gbGVmdF9qb2luKGdjb3VudHksIGRpcywgYnkgPSBjKCJmaXBzIiA9IGZpcHNfdGl0bGUpKQogIGZpbGxfdmFscyA8LSBnY291bnR5X3BvcFtjb2xfdmFsXQoKICAjIFBsb3QKICBpZiAobGVnZW5kX3RpdGxlID09ICIiKXsKICAgIGxlZ2VuZF90aXRsZSA8LSBjb2xfdmFsCiAgfQoKICBpZiAocGVyY2VudGlsZSA9PSBGQUxTRSl7CiAgICAjIG5hbWVzKGdjb3VudHlfcG9wKVtuYW1lcyhnY291bnR5X3BvcCkgPT0gY29sX3ZhbF0gPC0gImNvbF9vZl9pbnRlcmVzdCIKICAgIHBsdCA8LSBnZ3Bsb3QoZ2NvdW50eV9wb3ApICsKICAgICAgZ2VvbV9wb2x5Z29uKGFlcyhsb25nLCBsYXQsIGdyb3VwID0gZ3JvdXAsIGZpbGwgPSBnZXQoY29sX3ZhbCkpLAogICAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JleSIsIHNpemUgPSAwLjEsIG5hbWU9IlBlcmNlbnQgSW5mZWN0ZWQiKSArCiAgICAgIGdlb21fcG9seWdvbihhZXMobG9uZywgbGF0LCBncm91cCA9IGdyb3VwKSwKICAgICAgICAgICAgICAgICAgIGZpbGwgPSBOQSwgZGF0YSA9IGd1c2EsIGNvbG9yID0gImxpZ2h0Z3JleSIpICsKICAgICAgY29vcmRfbWFwKCJib25uZSIsIHBhcmFtZXRlcnMgPSA0MS42KSArIGdndGhlbWVzOjp0aGVtZV9tYXAoKSsKICAgICAgc2NhbGVfZmlsbF9ncmFkaWVudDIoKQogICAgICAgIyBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJ3aGl0ZSIsIGhpZ2ggPSAicmVkIiwgbmEudmFsdWUgPSAiZ3JleSIpCiAgICAgICMgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3VycyA9IHRlcnJhaW4uY29sb3JzKDEwKSkKICB9CgogIGlmIChwZXJjZW50aWxlID09IFRSVUUpewogICAgcGx0IDwtIGdncGxvdChnY291bnR5X3BvcCkgKwogICAgICBnZW9tX3BvbHlnb24oYWVzKGxvbmcsIGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IHBjbHMpLAogICAgICAgICAgICAgICAgICAgY29sb3IgPSAiZ3JleSIsIHNpemUgPSAwLjEpICsKICAgICAgZ2VvbV9wb2x5Z29uKGFlcyhsb25nLCBsYXQsIGdyb3VwID0gZ3JvdXApLAogICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLCBkYXRhID0gZ3VzYSwgY29sb3IgPSAibGlnaHRncmV5IikgKwogICAgICBjb29yZF9tYXAoImJvbm5lIiwgcGFyYW1ldGVycyA9IDQxLjYpICsgZ2d0aGVtZXM6OnRoZW1lX21hcCgpICsKICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXljb2xvcnMsIG5hLnZhbHVlID0gImdyZXkiKSArCiAgICAgICMgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJ2aXJpZGlzIiwgbmEudmFsdWUgPSAiZ3JleSIpICsKICAgICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiSGVsdmV0aWNhIiwgZmFjZSA9ICJib2xkIiwgc2l6ZSA9ICgxNSkpLAogICAgICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpLCAKICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImxlZnQiKQogIH0KICBwbHQgPC0gcGx0ICsgbGFicyhmaWxsPWxlZ2VuZF90aXRsZSkgKyBnZ3RpdGxlKGdyYXBoaWNfdGl0bGUpCiAgcGx0Cn0KYGBgCgpgYGB7cn0Kc3Vic2V0X2NlbnN1cwpgYGAKCmBgYHtyfQpzdWJzZXRfY2Vuc3VzWydwY3RfaW5mZWN0ZWQnXSA8LSBzdWJzZXRfY2Vuc3VzWydjb25maXJtZWRfY2FzZXMnXS9zdWJzZXRfY2Vuc3VzWyd0b3RhbF9wb3AnXQpzdWJzZXRfY2Vuc3VzWydwY3RfZGVhdGhzJ10gPC0gc3Vic2V0X2NlbnN1c1snZGVhdGhzJ10vc3Vic2V0X2NlbnN1c1sndG90YWxfcG9wJ10Kc3Vic2V0X2NlbnN1cyRjb3VudHlfZmlwc19jb2RlIDwtYXMuaW50ZWdlcihzdWJzZXRfY2Vuc3VzJGNvdW50eV9maXBzX2NvZGUpCnN1YnNldF9jZW5zdXMKYGBgCmBgYHtyfQpwbG90X3ZzX2NvdW50eShzdWJzZXRfY2Vuc3VzLCAicGN0X2luZmVjdGVkIiwgbGVnZW5kX3RpdGxlID0gIlBlcmNlbnQgSW5mZWN0ZWQiKQpwbG90X3ZzX2NvdW50eShzdWJzZXRfY2Vuc3VzLCAicGN0X2luZmVjdGVkIiwgcGVyY2VudGlsZSA9IFRSVUUsIGJhbmtzPTExLCAKICAgICAgICAgICAgICAgbGVnZW5kX3RpdGxlID0gIlBlcmNlbnRpbGUgSW5mZWN0ZWQiLAogICAgICAgICAgICAgICBncmFwaGljX3RpdGxlID0gIlBlcmNlbnRpbGUgb2YgUGVyY2VudGFnZSBvZiBQZW9wbGUgSW5mZWN0ZWQgYnkgQ291bnR5IikKcGxvdF92c19jb3VudHkoc3Vic2V0X2NlbnN1cywgInBjdF9kZWF0aHMiLCBwZXJjZW50aWxlID0gVFJVRSwgYmFua3M9MTEsIAogICAgICAgICAgICAgICBsZWdlbmRfdGl0bGUgPSAiUGVyY2VudGlsZSBEZWF0aHMiLAogICAgICAgICAgICAgICBncmFwaGljX3RpdGxlID0gIlBlcmNlbnRpbGUgb2YgUGVyY2VudGFnZSBvZiBEZWF0aHMgYnkgQ291bnR5IikKYGBgCgpgYGB7cn0KY2Vuc3VzX2NvcnJfY29scyA8LSBjKCJkZWF0aHMiLCAiY29uZmlybWVkX2Nhc2VzIiwgIm1lZGlhbl9pbmNvbWUiLCAibWFsZV9wb3AiLAogICAgICAgICAgICAgICAgICAgICAgImZlbWFsZV9wb3AiLCAidG90YWxfcG9wIiwgIm1lZGlhbl9hZ2UiLCAid29ya2VkX2F0X2hvbWUiKQpnZ2NvcnIoc3Vic2V0X2NlbnN1c1tjZW5zdXNfY29ycl9jb2xzXSwgbG93PSJyZWQiLCBtaWQ9ImdyZXkiLCBoaWdoPSJibHVlIiwgaGp1c3Q9IC43NSwgc2l6ZT0zLCAKICAgICAgIGxhYmVsID0gVFJVRSwgbGFiZWxfc2l6ZSA9IDMsIGxhYmVsX2NvbG9yID0gIndoaXRlIikgKyBnZ3Bsb3QyOjpsYWJzKHRpdGxlID0gIlBlYXJzb24gQ29ycmVsYXRpb24gb2YgSW1wb3J0YW50IFZhcmlhYmxlcyIpCmBgYApgYGB7cn0KZ2xvYmFsX21vYmlsaXR5X3JlcG9ydApgYGAKCgpgYGB7cn0KY291bnRyeV9kYXRlX3BjdF9jaGFuZ2UgPC0gZ2xvYmFsX21vYmlsaXR5X3JlcG9ydCAlPiUgc2VsZWN0KGNvdW50cnlfcmVnaW9uX2NvZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgY29udGFpbnMoImRhdGUiKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgY29udGFpbnMoInBlcmNlbnQiKSkKY291bnRyeV9kYXRlX3BjdF9jaGFuZ2UKYGBgCmBgYHtyfQpjb2lfZG93bnNhbXBsZWQgPC0gY291bnRyeV9kYXRlX3BjdF9jaGFuZ2UgJT4lIGZpbHRlcihjb3VudHJ5X3JlZ2lvbl9jb2RlICVpbiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiVVMiLCAiQ0EiLCAiTloiLCAiQUUiKSkgJT4lIAogIGZpbHRlcih3ZWVrZGF5cyhkYXRlKSA9PSAiTW9uZGF5IikgJT4lIGdyb3VwX2J5KGNvdW50cnlfcmVnaW9uX2NvZGUsIGRhdGUpICU+JSBzdW1tYXJpc2VfYWxsKG1lYW4sIG5hLnJtID0gVCkgJT4lIGFycmFuZ2UoZGF0ZSkKY29pX2Rvd25zYW1wbGVkCmBgYAoKCgpgYGB7cn0KZ2dwbG90KGNvaV9kb3duc2FtcGxlZCwKICAgICAgIGFlcyh4PWRhdGUsIHk9Z3JvY2VyeV9hbmRfcGhhcm1hY3lfcGVyY2VudF9jaGFuZ2VfZnJvbV9iYXNlbGluZSwgZ3JvdXA9Y291bnRyeV9yZWdpb25fY29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPWNvdW50cnlfcmVnaW9uX2NvZGUpKSsKICBnZW9tX3BvaW50KGFlcyh5PXJvbGxtZWFuKHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCBrPTIwLCBuYS5wYWQ9VFJVRSkpLCBzaXplPS41KQogICMgZ2VvbV9saW5lKGFlcyh5PXJvbGxtZWFuKHJldGFpbF9hbmRfcmVjcmVhdGlvbl9wZXJjZW50X2NoYW5nZV9mcm9tX2Jhc2VsaW5lLCBrPTUwLCBuYS5wYWQ9VFJVRSkpKQogICMgZ2VvbV9saW5lKCkKYGBgCgpgYGB7cn0KY29pX2Rvd25zYW1wbGVkCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgo=